package com.lw.common.web.controller.base;

import java.util.Iterator;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import com.alibaba.fastjson.JSON;
import com.lw.common.basemodel.Json;
import com.lw.common.constant.BaseConstant;
import com.lw.common.constant.GolbalConstant;
import com.lw.common.constant.LoginConstant;

/**
 * 
 * @Title: BasicController.java
 * @Description: (基础的控制类)
 * @author 刘伟 15818570028@163.com
 * @date 2016年10月2日 下午5:32:35
 * @version V1.0
 */

public class BasicController {
	private static final Logger LOG = LoggerFactory.getLogger(BasicController.class);

	/**
	 * 
	 * @Description: (异常处理)
	 * @return Json 返回类型
	 * 
	 */
	@ExceptionHandler(Exception.class)
	public Json exceptionHandler(Exception ex) {
		if (ex instanceof UnknownAccountException) {
			LOG.info(GolbalConstant.LOG_MARK + LoginConstant.LOGIN_UNACCOUNT + ex.getMessage());
			return setFailed(LoginConstant.LOGIN_UNACCOUNT);
		} else if (ex instanceof IncorrectCredentialsException) {
			LOG.info(ex.getMessage());
			LOG.info(GolbalConstant.LOG_MARK + LoginConstant.LOGIN_FAIL);
			LOG.info(GolbalConstant.LOG_MARK + ex.getStackTrace());
			return setFailed(LoginConstant.LOGIN_FAIL);
		} else if (ex instanceof LockedAccountException) {
			LOG.info(GolbalConstant.LOG_MARK + LoginConstant.LOCKED_ACCOUNT + ex.getMessage());
			return setFailed(GolbalConstant.LOG_MARK);
		} else if (ex instanceof AuthenticationException) {
			LOG.info(GolbalConstant.LOG_MARK + LoginConstant.LOGIN_AUTHENTICATION);
			LOG.info(GolbalConstant.LOG_MARK + ex.getStackTrace());
			return setFailed(LoginConstant.LOGIN_AUTHENTICATION);
		} else if (ex instanceof MissingServletRequestParameterException) {
			LOG.error(GolbalConstant.LOG_MARK + ex.getMessage());
			return setFailed(BaseConstant.OPERATOR_MISSSREQUESTPRARM, ex.getMessage());
			// 待定自定义异常
		} else if (ex instanceof MethodArgumentTypeMismatchException) {
			LOG.error(GolbalConstant.LOG_MARK + ex.getMessage());
			return setFailed(BaseConstant.OPERATOR_MISSSREQUESTPRARM, ex.getMessage());
		} else if (ex instanceof BindException) {
			LOG.error(GolbalConstant.LOG_MARK + ex.getMessage());
			return setFailed(BaseConstant.OPERATOR_MISSSREQUESTPRARM, ex.getMessage());
		} else if (ex instanceof ConstraintViolationException) {
			ConstraintViolationException e = (ConstraintViolationException) ex;
			Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
			Iterator<ConstraintViolation<?>> it = constraintViolations.iterator();
			ConstraintViolation<?> c = it.next();
			return setFailed(BaseConstant.OPERATOR_MISSSREQUESTPRARM, c.getMessageTemplate());
		}
		LOG.error(GolbalConstant.LOG_MARK, ex);
		return setFailed(HttpStatus.BAD_REQUEST.name());
	}

	/**
	 * 
	 * @Description: (标准格式设置成功响应代码)
	 * 
	 */
	protected ResponseEntity<ModelMap> setSuccessModelMap(ModelMap modelMap) {
		return setSuccessModelMap(modelMap, null);
	}

	/**
	 * @Description: (标准格式设置成功响应代码)
	 * 
	 */
	protected ResponseEntity<ModelMap> setSuccessModelMap(ModelMap modelMap, Object data) {
		return setModelMap(modelMap, HttpStatus.OK, data, null);
	}

	/**
	 * 
	 * @Description: (标准格式设置成功响应代码)
	 * 
	 */
	protected ResponseEntity<ModelMap> setModelMap(ModelMap modelMap, HttpStatus code) {
		return setModelMap(modelMap, code, null, null);
	}

	/**
	 * 
	 * @Title: setModelMap
	 */
	protected ResponseEntity<ModelMap> setModelMap(ModelMap modelMap, HttpStatus code, Object data, String msg) {
		modelMap.remove("void");
		if (data != null) {
			modelMap.put("data", data);
		}
		modelMap.put("HttpStatus", code.value());
		modelMap.put("msg", msg);
		return ResponseEntity.ok(modelMap);
	}

	/**
	 * 
	 * @Title: setSimpleSuccess
	 * @Description: (简单设置成功)
	 */
	protected Json setSimpleSuccess() {
		return setSimpleSuccess(null);
	}

	/**
	 * 
	 * @Description: (简单设置成功)
	 * 
	 */
	protected Json setSimpleSuccess(Object obj) {
		return setSimpleSuccess(BaseConstant.OPERATOR_SUCESSCE, obj);
	}

	/**
	 * 
	 * @Title: setSimpleSuccess
	 * @Description: (快速设置失败)
	 * @param @param
	 *            msg 返回的提示信息
	 * @param @param
	 *            obj 返回的数据集
	 * @param @return
	 * @return 返回类型 Json
	 * 
	 */
	protected Json setSimpleSuccess(String msg, Object obj) {
		return new Json().setMsg(msg).setObj(obj).setSuccess(true);
	}

	/**
	 * 
	 * @Title: setFailed
	 * @Description: (快速失败)
	 * @return 返回类型 Json
	 * 
	 */
	protected Json setFailed() {
		return setFailed(BaseConstant.OPERATOR_FAIL);
	}

	/**
	 * 
	 * @Title: setFailed
	 * @Description: (快速设置失败)
	 * @param @param
	 *            msg 失败的提示信息
	 * @param @return
	 * @return 返回类型 Json
	 * 
	 */
	protected Json setFailed(String msg) {
		return setFailed(msg, null);
	}

	/**
	 * 
	 * @Title: setFailed
	 * @Description: (快速设置失败)
	 * @return 返回类型 Json
	 * 
	 */
	protected Json setFailed(String msg, Object obj) {
		return new Json().setMsg(msg).setObj(obj);
	}

}
